Remove bind_evtchn_to_irq/unbind_evtchn_from_irq from the
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Fri, 7 Oct 2005 10:54:38 +0000 (11:54 +0100)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Fri, 7 Oct 2005 10:54:38 +0000 (11:54 +0100)
evtchn kernel interface. Fix error path in bind_evtchn_to_irqhandler.
Fix backend drivers to avoid double freeing IRQs.

Signed-off-by: Keir Fraser <keir@xensource.com>
linux-2.6-xen-sparse/arch/ia64/xen/drivers/evtchn_ia64.c
linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c
linux-2.6-xen-sparse/drivers/xen/blkback/interface.c
linux-2.6-xen-sparse/drivers/xen/netback/interface.c
linux-2.6-xen-sparse/include/asm-xen/evtchn.h

index e5c3a50f78a725c9eb02955237db00862419b14e..f6e6c9ee72dde760cc8ae824f82cf639b3de7a15 100644 (file)
@@ -67,12 +67,6 @@ void unbind_evtchn_from_irqhandler(unsigned int evtchn, void *dev_id)
     evtchns[evtchn].handler = NULL;
 }
 
-void unbind_evtchn_from_irq(unsigned int evtchn)
-{
-       printk("unbind_evtchn_from_irq called... FIXME??\n");
-       while(1);
-}
-
 irqreturn_t evtchn_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
     u32            l1, l2;
index a709dd4198f4e6148a1d2e983429c1dedb5c1d35..6a85441f7f769bdf3d994e8d448ab2e8ad973cbe 100644 (file)
@@ -296,7 +296,7 @@ void unbind_ipi_from_irq(int ipi)
 }
 EXPORT_SYMBOL(unbind_ipi_from_irq);
 
-int bind_evtchn_to_irq(unsigned int evtchn)
+static int bind_evtchn_to_irq(unsigned int evtchn)
 {
        int irq;
 
@@ -314,9 +314,8 @@ int bind_evtchn_to_irq(unsigned int evtchn)
     
        return irq;
 }
-EXPORT_SYMBOL(bind_evtchn_to_irq);
 
-void unbind_evtchn_from_irq(unsigned int irq)
+static void unbind_evtchn_from_irq(unsigned int irq)
 {
        evtchn_op_t op = { .cmd = EVTCHNOP_close };
        int evtchn = irq_to_evtchn[irq];
@@ -333,7 +332,6 @@ void unbind_evtchn_from_irq(unsigned int irq)
 
        spin_unlock(&irq_mapping_update_lock);
 }
-EXPORT_SYMBOL(unbind_evtchn_from_irq);
 
 int bind_evtchn_to_irqhandler(
        unsigned int evtchn,
@@ -347,8 +345,10 @@ int bind_evtchn_to_irqhandler(
 
        irq = bind_evtchn_to_irq(evtchn);
        retval = request_irq(irq, handler, irqflags, devname, dev_id);
-       if (retval != 0)
+       if (retval != 0) {
                unbind_evtchn_from_irq(irq);
+               return retval;
+       }
 
        return irq;
 }
index 458d6e9c361c232bcd40b16b06d115ab3dcbbbfc..ee1889a09ad12b5dd89cd9edaac3967dfb10b16a 100644 (file)
@@ -74,6 +74,10 @@ int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn)
                .u.bind_interdomain.remote_dom = blkif->domid,
                .u.bind_interdomain.remote_port = evtchn };
 
+       /* Already connected through? */
+       if (blkif->irq)
+               return 0;
+
        if ( (blkif->blk_ring_area = alloc_vm_area(PAGE_SIZE)) == NULL )
                return -ENOMEM;
 
@@ -107,8 +111,12 @@ static void free_blkif(void *arg)
 {
        blkif_t *blkif = (blkif_t *)arg;
 
-       if (blkif->irq)
-               unbind_evtchn_from_irqhandler(blkif->irq, blkif);
+       /* Already disconnected? */
+       if (!blkif->irq)
+               return;
+
+       unbind_evtchn_from_irqhandler(blkif->irq, blkif);
+       blkif->irq = 0;
 
        vbd_free(&blkif->vbd);
 
index 3e4537c90f998c799d7b3fdf5acaca703fe6cddf..43f516badff187ab646c4be0327f2bb2979ce448 100644 (file)
@@ -183,6 +183,10 @@ int netif_map(netif_t *netif, unsigned long tx_ring_ref,
                .u.bind_interdomain.remote_dom = netif->domid,
                .u.bind_interdomain.remote_port = evtchn };
 
+       /* Already connected through? */
+       if (netif->irq)
+               return 0;
+
        netif->comms_area = alloc_vm_area(2*PAGE_SIZE);
        if (netif->comms_area == NULL)
                return -ENOMEM;
@@ -227,13 +231,12 @@ static void free_netif_callback(void *arg)
 {
        netif_t *netif = (netif_t *)arg;
 
-       /*
-        * This can't be done in netif_disconnect() because at that point
-        * there may be outstanding requests in the network stack whose
-        * asynchronous responses must still be notified to the remote driver.
-        */
-       if (netif->irq)
-               unbind_evtchn_from_irqhandler(netif->irq, netif);
+       /* Already disconnected? */
+       if (!netif->irq)
+               return;
+
+       unbind_evtchn_from_irqhandler(netif->irq, netif);
+       netif->irq = 0;
 
        unregister_netdev(netif->dev);
 
index c9feb34606a8a285a88258959e8d202e89eefd43..a38b8732a150eae16256a2826d4fe1e878de5761 100644 (file)
@@ -51,14 +51,6 @@ extern void unbind_virq_from_irq(int virq);
 extern int  bind_ipi_to_irq(int ipi);
 extern void unbind_ipi_from_irq(int ipi);
 
-/*
- * Dynamically bind an event-channel port to Linux IRQ space.
- * BIND:   Returns IRQ or error.
- * UNBIND: Takes IRQ to unbind from; automatically closes the event channel.
- */
-extern int  bind_evtchn_to_irq(unsigned int evtchn);
-extern void unbind_evtchn_from_irq(unsigned int irq);
-
 /*
  * Dynamically bind an event-channel port to an IRQ-like callback handler.
  * On some platforms this may not be implemented via the Linux IRQ subsystem.